#pragma once

#include "RBM.h"

using namespace loirey;

namespace nw_rbm
{
	class CUnitPooling : public CUnitConnections
	{
	public:
		int State;
		RBM_FLOAT BiasValue;
		RBM_FLOAT ExtraEnergy, Expectation;
		//RBM_FLOAT DerivativeFactor_SpaCod;

	public:
		CUnitPooling();
		virtual void Clear();
	};

	class CRBM_with_MaxPooling : public CRestrictedBoltzmannMachine
	{
	public:
		typedef CSimpleTypeArray<CUnitPooling>		CList_UnitPooling;
	public:
		int AmountUnit_Pooling;
		CList_UnitPooling ListUnit_Pooling;
		CSimpleTypeArray<int> ListIndex_MP_Unit_PerHidden;
		CSimpleTypeArray<int> ListIndex_MP_Brother_PerHidden;

	public:
		CRBM_with_MaxPooling();
	public:
		virtual void ClearUnitSettings();
	public:
		virtual void SetState_of_Units_Pooling(const int* SrcPtrState);
		virtual void SetState_of_Units_Pooling(const CSimpleTypeArray<int>& SrcListState);
		virtual void GetState_of_Units_Pooling(RBM_FLOAT* DstPtrState) const;
		virtual const RBM_FLOAT* GetState_of_Units_Pooling(CSimpleTypeArray<RBM_FLOAT>& DstListState) const;
	public:
		virtual void CheckPoolingState_and_UpdateHiddenState();
	public:
		virtual void InitAmountUnit_Pooling(int AmountUnit_Pooling);
		virtual int NewUnit_Pooling();
	public:
		virtual int NewUnit_Hidden(
			bool fIsRealValued, RBM_FLOAT Sigma, int WeightItemIndex_Hidden);
		virtual int NewUnit_Hidden(
			int WeightItemIndex_Hidden);
		virtual void NewRelation_MaxPooling(
			int UnitIndex_Hidden, int UnitIndex_Pooling);
	public:
		virtual const RBM_FLOAT* MakeHiddenDerivative_for_SparseCoding(
			CSimpleTypeArray<RBM_FLOAT>& vHiddenDerivative);
		virtual void UpdateUnitsBiasValue_Pooling();
	public:
		virtual void ClearMaxPoolingUnitsExtraEnergy();
	public:
		virtual void ComputeExpectation_of_Units_Hidden();
		virtual void ComputeBiasOnlyExpectation_of_Units_Hidden();
		virtual void SampleState_of_Units_Hidden();
		virtual void SampleState_of_Units_Hidden_GivenPoolingState();
	};

}

